package com.qhx.backme.service.impl;

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.qhx.backme.exception.SupplyChainException;
import com.qhx.backme.exception.WeBaseFrontException;
import com.qhx.backme.model.Result;
import com.qhx.backme.model.to.TransactionTO;
import com.qhx.backme.model.vo.ResultVO;
import com.qhx.backme.service.TransactionService;
import com.qhx.backme.util.HttpUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * 交易Service实现类
 *
 * @author: qhx20040819
 * @date: 2023-10-24 08:25
 **/
@Service
public class TransactionServiceImpl implements TransactionService {
    @Autowired
    private HttpUtil httpUtil;

    /**
     * 银行对公收款
     *
     * @param transactionTO 交易传输对象
     * @return 交易结果
     */
    @Override
    public Result<String> bankToCompanyReceipt(TransactionTO transactionTO) {
        // 调用统一公共交易方法，指定合约函数为"bankToCompanyReceipt"
        return userToUserReceipt(transactionTO, "bankToCompanyReceipt");
    }

    /**
     * 公司间收款
     *
     * @param transactionTO 交易传输对象
     * @return 交易结果
     */
    @Override
    public Result<String> companyToCompanyReceipt(TransactionTO transactionTO) {
        // 调用统一公共交易方法，指定合约函数为"companyToCompanyReceipt"
        return userToUserReceipt(transactionTO, "companyToCompanyReceipt");
    }

    /**
     * 公司对银行收款
     *
     * @param transactionTO 交易传输对象
     * @return 交易结果
     */
    @Override
    public Result<String> companyToBankReceipt(TransactionTO transactionTO) {
        // 调用统一公共交易方法，指定合约函数为"companyToBankReceipt"
        return userToUserReceipt(transactionTO, "companyToBankReceipt");
    }

    /**
     * 统一公共交易封装
     *
     * @param transactionTO 交易传输对象
     * @param contractFun   合约函数名
     * @return 交易结果
     */
    private Result<String> userToUserReceipt(TransactionTO transactionTO, String contractFun) {
        // 准备交易参数
        List<Object> params = new ArrayList<>();
        params.add(transactionTO.getSenderAddress());
        params.add(transactionTO.getAccepterAddress());
        params.add(transactionTO.getAmount());
        params.add(transactionTO.getReceiptType());

        // 发起合约请求
        String _result = httpUtil.contractRequest(transactionTO.getAccepterAddress(), contractFun, params);

        // 处理合约请求错误
        if (_result.contains("errorMessage")) {
            throw new SupplyChainException(ResultVO.CONTRACT_ERROR);
        }

        // 解析合约响应
        JSONObject jsonObject = JSONUtil.parseObj(_result);
        String output = jsonObject.getStr("output").substring(2);
        int resCode = Integer.parseInt(output, 16);

        // 处理合约自定义错误码
        if (resCode == 404001) {
            throw new WeBaseFrontException(ResultVO.COMPANY_NOT_EXIST.getMes());
        } else if (resCode == 404002) {
            throw new WeBaseFrontException(ResultVO.BANK_NOT_EXIST.getMes());
        } else if (resCode == 404003) {
            throw new WeBaseFrontException(ResultVO.AMOUNT_NOT_ENOUGH.getMes());
        }

        // 返回交易成功结果
        return Result.success("交易成功");
    }
}
